﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using Utils;
using Log;
using System.IO;
using System.Threading;
using System.Diagnostics;
using System.Globalization;
using System.Media;
using System.Drawing.Drawing2D;

namespace AutoTrader
{
    public partial class AutoTraderForm 
    {
        double dBuyPrice = 0, dSellPrice = 0, dHiPrice = 0, dLowPrice = 0;
        int errNumber = 0;

        int CalculateProgressPos()
        {
            int Pos = 0;

            if (BaseOrder.TopBorder == 0 || BaseOrder.BottomBorder == 0 || SellPrice == 0 || BuyPrice == 0)
            {
                Pos = 0;
            }
            else if (BaseOrder.BuyOrSell == "1")// sell
            {
                Pos = Convert.ToInt32((BaseOrder.TopBorder - SellPrice) / (BaseOrder.BottomBorder - BaseOrder.TopBorder) * 100m);
            }
            else
            {
                Pos = Convert.ToInt32((BaseOrder.BottomBorder + BuyPrice) / (BaseOrder.TopBorder - BaseOrder.BottomBorder) * 100m);
            }

            return Pos;
        }

        void ClosePositionForce()
        {
            FailedCount = 0;
            obj.ClosePosition(Settings.Settings.Instrument);// cancel opened order
            myLogger.Add(string.Format("Opened position closed."));
            myLogger.Add(string.Format("Current Result: {0} {1}", dResultAll.ToString("F3", CultureInfo.InvariantCulture), Settings.Settings.Instrument.Substring(4, 3)));
            obj.CancelOrder(StopOrder.ID);
            BaseOrder.ID = 0;
            StopOrder.ID = 0;
            bClosePosition = false;
            WriteOrderSettings();
        }

        // get courses and order result
        bool GetQuotes( BackgroundWorker worker )
        {
            obj.GetQuote( Settings.Settings.Instrument, ref dBuyPrice, ref dSellPrice, ref dHiPrice, ref dLowPrice, ref errNumber );
            if (errNumber < 0)
            {
                myLogger.Add(string.Format("GetQuote fail. {0}", obj.GetErrDescription(errNumber)));
                return false; ;
            }
            BuyPrice = Convert.ToDecimal(dBuyPrice);
            SellPrice = Convert.ToDecimal(dSellPrice);

            CalculateProgressPos();

            worker.ReportProgress(progressPosition);

            dResultAll = obj.GetTotalResult(Settings.Settings.Instrument.Substring(4, 3), ref errNumber);
            if (errNumber < 0)
            {
                myLogger.Add(string.Format("Get Total Result Error.{0}", obj.GetErrDescription(errNumber)));
            }

            if( 0 == BaseOrder.ID )//if 0 there is no order - create one but first get two steps to decide buy or sell
            {
                if (!OpenOrders())
                {
                    myLogger.Add(string.Format("OpenOrders fail. "));
                    return false;
                }
            }

            return true;
        }

        private void backgroundTrader_DoWork(object sender, DoWorkEventArgs e)
        {
            string message = string.Empty;
            string format_string = string.Empty;
            double dPositionCount=0, dPositionPrice=0, dPositionResult=0;

            BackgroundWorker worker = sender as BackgroundWorker;

            StopOrderTriggered = false;

///         main cicle
            try
            {
                //Create 
                myLogger.Add("Job started.");
                errNumber = obj.CreateClientAPI(strExtNumber);

                if (errNumber >= 0)
                {
                    myLogger.Add(string.Format("Cleint API Created for ExtNumber:{0}", strExtNumber));
                }
                else
                {
                    myLogger.Add(string.Format("CreateClientAPI fail. {0}", obj.GetErrDescription(errNumber)));
                    obj.DestroyClientAPI();
                    return;
                }

                if (!ReadOrderSettings())
                    return;

                if (!ReadCoursesSettings())
                    return;

                do
                {
                    if ((worker.CancellationPending == true))
                    {
                        e.Cancel = true;
                        break;
                    }
                    else
                    {
                        //GetQuote
                        Thread.Sleep(100);
                    }

                    GetQuotes(worker);

                    if (0 == BaseOrder.ID)//if 0 there is no order - create one but first get two steps to decide buy or sell
                    {
                        if (!OpenOrders())
                        {
                            myLogger.Add(string.Format("OpenOrders fail. "));
                            break;
                        }
                    }

                    worker.ReportProgress(CalculateProgressPos());

                    if (!CheckPosition(ref dPositionCount, ref dPositionPrice, ref dPositionResult)) // check to position - if exists OK...if not cancel Stop order and create new
                    {
                        myLogger.Add(string.Format("CheckPosition fail. "));
                        break;
                    }

                    if (bClosePosition)
                    {
                        ClosePositionForce();
                        break;
                    }

                }
                while (true);
            }
            catch (Exception ex)
            {
                myLogger.Add(string.Format("Runtime exception: {0}", ex.Message));
            }
            finally
            {
                // Destroy
                errNumber = obj.DestroyClientAPI();
                if (errNumber >= 0)
                    myLogger.Add(string.Format("Cleint API Closed "));
                else
                    myLogger.Add(string.Format("DestroyClientAPI fail. {0}", obj.GetErrDescription(errNumber)));
                myLogger.Add("Job finished.");

            }

        }

        private void backgroundTrader_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            txtBuy.Text = BuyPrice.ToString();
            txtSell.Text = SellPrice.ToString();

            txtBaseOrder.Text = BaseOrder.ID.ToString();
            txtBaseLots.Text = BaseOrder.Lots.ToString();
            txtBaseBuyOrSell.Text = BaseOrder.BuyOrSell;
            txtBasePrice.Text = BaseOrder.Price.ToString();

            txtStopOrder.Text = StopOrder.ID.ToString();
            txtStopLots.Text = StopOrder.Lots.ToString();
            txtStopBuyOrSell.Text = StopOrder.BuyOrSell;
            txtStopPrice.Text = StopOrder.Price.ToString();
            lblTotalResult.Text = string.Format("Total Result: {0} {1}", dResultAll.ToString("F3", CultureInfo.InvariantCulture), Settings.Settings.Instrument.Substring(4, 3));

            if ( StopOrder.ID > 0 )
                btClosePos.Enabled = true;
            else
                btClosePos.Enabled = false;

            int value = e.ProgressPercentage;
            decimal top = 0.0m;
            progressBar.Value = value;
            lblStop.Text = string.Format( "Stop at {0}", StopOrder.Price.ToString() );

            if( BaseOrder.BuyOrSell == "1" )// sell
            {
                //top = Settings.Settings.TopBorder; 
                lblSell.Font = fontBold;
                lblBuy.Font = fontRegular;
            }
            else
            {
                top = StopOrder.Price + 2 * PipsStep + PipsStep * 0.2m;
                lblSell.Font = fontRegular;
                lblBuy.Font = fontBold;
            }

            lblReorder.Text = string.Format("Reorder at {0}", top.ToString());
        }

        private void backgroundTrader_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            btStart.Enabled = true;
            btStop.Enabled = false;
            btExit.Enabled = true;
            cbInstruments.Enabled = true;
            textClientNumber.Enabled = true;
            cbInitialLots.Enabled = true;
            cbMaxDouble.Enabled = true;
            cbPipsStep.Enabled = true;
            chSmartStep.Enabled = true;
            chAutoStart.Enabled = true;
        }
    }
}